package com.amumu.drama.common.modules.service.impl.sms;


import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.amumu.drama.common.config.AliyunProperties;
import com.amumu.drama.common.modules.service.impl.sms.model.SendSmsRequest;
import com.amumu.drama.common.modules.service.impl.sms.model.SmsResponse;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Service;

/**
 * @author robotto
 * @version 1.0
 * @date 2022/5/14 23:51
 **/

@Service
@ConditionalOnProperty(prefix = "config.sms", name = "type", havingValue = "aliyun", matchIfMissing = true)
public class AliyunCaptchaServiceImpl extends AbstractCaptchaService {
    private final AliyunProperties properties;
    private final IAcsClient client;

    public AliyunCaptchaServiceImpl(AliyunProperties properties) {
        this.properties = properties;
        this.client = this.getClient();
    }

    /**
     * 发送短信验证码response
     * {
     * "RequestId": "614048FB-0619-4439-A1D5-AA8B218A****",
     * "Message": "OK",
     * "BizId": "386715418801811068^0",
     * "Code": "OK"
     * }
     *
     * @param sendSmsRequest smsRequest     短信模板参数
     * @return
     */
    @Override
    protected SmsResponse doSendMessage(SendSmsRequest sendSmsRequest) {

        String message = "测试环境未开放注册登陆";
        boolean result = false;
        if (properties.getEnableSmsCaptcha()) {
            try {
                logger.info("aliyun sned sms request {}", sendSmsRequest);
                SendSmsResponse response = client.getAcsResponse(sendSmsRequest.getAliyunSendSmsRequest());
                logger.info("aliyun sms response {}", response);
                result = SUCCESS_CODE.equals(response.getCode());
                message = response.getMessage();
            } catch (ClientException e) {
                logger.error("aliyun sms send error", e);
                this.printClientExceptionMsg(e);
                message = e.getMessage();
                result = false;
            }
        }

        SmsResponse smsResponse = new SmsResponse();
        smsResponse.setMessage(message);
        smsResponse.setResult(result);
        return smsResponse;
    }

    /**
     * 获取短信请求
     *
     * @param phoneNo
     * @param params
     * @return
     */
    @Override
    protected SendSmsRequest buildSmsCaptchaRequest(String phoneNo, String params) {
        com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest request = new com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest();
        request.setSignName(properties.getSignName());   // 短信签名名称
        request.setTemplateCode(properties.getSmsCaptchaTemplateCode());              // 短信模板CODE
        request.setPhoneNumbers(phoneNo);                  // 接收短信的手机号码
        request.setTemplateParam(params);              // 短信模板变量对应的实际值

        SendSmsRequest sendSmsRequest = new SendSmsRequest();
        sendSmsRequest.setAliyunSendSmsRequest(request);
        return sendSmsRequest;
    }

    /**
     * 连接阿里云：
     * <p>
     * 三个参数：
     * regionId 不要动，默认使用官方的
     * accessKeyId 自己的用户accessKeyId
     * accessSecret 自己的用户accessSecret
     */
    private IAcsClient getClient() {
        IClientProfile profile = DefaultProfile.getProfile(properties.getRegionId(),
                properties.getAccessKeyId(),
                properties.getAccessKeySecret());
        return new DefaultAcsClient(profile);
    }

    /**
     * 打印错误日志
     *
     * @param e
     */
    protected void printClientExceptionMsg(ClientException e) {
        logger.error("获取短信发送服务机发生错误。错误代码是 [{}]，错误消息是 [{}]，错误请求ID是 [{}]，错误Msg是 [{}]，错误类型是 [{}]",
                e.getErrCode(),
                e.getMessage(),
                e.getRequestId(),
                e.getErrMsg(),
                e.getErrorType());
    }
}
